<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>整理输入文本 | Elasticsearch: 权威指南 | Elastic</title>
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
</head>
<body>
<div class="main-container">
    <section id="content">
        
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原文地址: <a href="https://www.elastic.co/guide/cn/elasticsearch/guide/current/char-filters.html" rel="nofollow">https://www.elastic.co/guide/cn/elasticsearch/guide/current/char-filters.html</a>, 版权归 www.elastic.co 所有<br/>
                            英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/char-filters.html" rel="nofollow">https://www.elastic.co/guide/en/elasticsearch/guide/current/char-filters.html</a>
                            </div>
                        <!-- start body -->
                  <div class="page_header">
<b>请注意:</b><br>本书基于 Elasticsearch 2.x 版本，有些内容可能已经过时。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: 权威指南</a></span>
»
<span class="breadcrumb-link"><a href="languages.html">处理人类语言</a></span>
»
<span class="breadcrumb-link"><a href="identifying-words.html">词汇识别</a></span>
»
<span class="breadcrumb-node">整理输入文本</span>
</div>
<div class="navheader">
<span class="prev">
<a href="icu-tokenizer.html">« icu_分词器</a>
</span>
<span class="next">
<a href="token-normalization.html">归一化词元 »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="char-filters"></a>整理输入文本<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/210_Identifying_words/50_Tidying_text.asciidoc">edit</a>
</h2>
</div></div></div>
<p>当输入文本是干净的时候分词器提供最佳分词结果，有效文本，这里 <em>有效</em> 指的是遵从 Unicode 算法期望的标点符号规则。
然而很多时候，我们需要处理的文本会是除了干净文本之外的任何文本。在分词之前整理文本会提升输出结果的质量。</p>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_html_分词"></a>HTML 分词<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/210_Identifying_words/50_Tidying_text.asciidoc">edit</a>
</h3>
</div></div></div>
<p>将 HTML 通过 <code class="literal">标准分词器</code> 或 <code class="literal">icu_分词器</code> 分词将产生糟糕的结果。这些分词器不知道如何处理 HTML 标签。例如：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">GET /_analyze?tokenizer=standard
&lt;p&gt;Some d&amp;eacute;j&amp;agrave; vu &lt;a href="http://somedomain.com&gt;"&gt;website&lt;/a&gt;</pre>
</div>
<p><code class="literal">标准分词器</code> 会混淆 HTML 标签和实体，并且输出以下词汇单元： <code class="literal">p</code> 、 <code class="literal">Some</code> 、 <code class="literal">d</code> 、 <code class="literal">eacute</code> 、 <code class="literal">j</code> 、 <code class="literal">agrave</code> 、 <code class="literal">vu</code> 、 <code class="literal">a</code> 、
<code class="literal">href</code> 、 <code class="literal">http</code> 、 <code class="literal">somedomain.com</code> 、 <code class="literal">website</code> 、 <code class="literal">a</code> 。这些词汇单元显然不知所云！</p>
<p><em>字符过滤器</em> 可以添加进分析器中，在将文本传给分词器之前预处理该文本。在这种情况下，我们可以用 <code class="literal">html_strip</code> 字符过滤器移除 HTML 标签并编码 HTML 实体如 <code class="literal">&amp;eacute;</code> 为一致的 Unicode 字符。</p>
<p>字符过滤器可以通过 <code class="literal">analyze</code> API 进行测试，这需要在查询字符串中指明它们：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">GET /_analyze?tokenizer=standard&amp;char_filters=html_strip
&lt;p&gt;Some d&amp;eacute;j&amp;agrave; vu &lt;a href="http://somedomain.com&gt;"&gt;website&lt;/a&gt;</pre>
</div>
<p>想将它们作为分析器的一部分使用，需要把它们添加到 <code class="literal">custom</code> 类型的自定义分析器里：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">PUT /my_index
{
    "settings": {
        "analysis": {
            "analyzer": {
                "my_html_analyzer": {
                    "tokenizer":     "standard",
                    "char_filter": [ "html_strip" ]
                }
            }
        }
    }
}</pre>
</div>
<p>一旦自定义分析器创建好之后， 我们新的 <code class="literal">my_html_analyzer</code> 就可以用 <code class="literal">analyze</code> API 测试：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">GET /my_index/_analyze?analyzer=my_html_analyzer
&lt;p&gt;Some d&amp;eacute;j&amp;agrave; vu &lt;a href="http://somedomain.com&gt;"&gt;website&lt;/a&gt;</pre>
</div>
<p>这次输出的词汇单元才是我们期望的： <code class="literal">Some</code> ， <code class="literal">déjà</code> ， <code class="literal">vu</code> ， <code class="literal">website</code> 。</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_整理标点符号"></a>整理标点符号<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/210_Identifying_words/50_Tidying_text.asciidoc">edit</a>
</h3>
</div></div></div>
<p><code class="literal">标准分词器</code> 和 <code class="literal">icu_分词器</code> 都能理解单词中的撇号应当被视为单词的一部分，然而包围单词的单引号在不应该。分词文本  <code class="literal">You're my 'favorite'</code> ，
会被输出正确的词汇单元 <code class="literal">You're ， my ， favorite</code> 。</p>
<p>不幸的是， Unicode 列出了一些有时会被用为撇号的字符：</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">U+0027</code>
</span>
</dt>
<dd>
撇号标记为 (<code class="literal">'</code>)— 原始 ASCII 符号
</dd>
<dt>
<span class="term">
<code class="literal">U+2018</code>
</span>
</dt>
<dd>
左单引号标记为 (<code class="literal">‘</code>)— 当单引用时作为一个引用的开始
</dd>
<dt>
<span class="term">
<code class="literal">U+2019</code>
</span>
</dt>
<dd>
右单引号标记为 (<code class="literal">’</code>)— 当单引用时座位一个引用的结束，也是撇号的首选字符。
</dd>
</dl>
</div>
<p>当这三个字符出现在单词中间的时候， <code class="literal">标准分词器</code> 和 <code class="literal">icu_分词器</code> 都会将这三个字符视为撇号（这会被视为单词的一部分）。
然而还有另外三个长得很像撇号的字符：</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">U+201B</code>
</span>
</dt>
<dd>
Single high-reversed-9 （高反单引号）标记为  (<code class="literal">‛</code>)— 跟 <code class="literal">U+2018</code> 一样，但是外观上有区别
</dd>
<dt>
<span class="term">
<code class="literal">U+0091</code>
</span>
</dt>
<dd>
ISO-8859-1 中的左单引号 — 不会被用于 Unicode 中
</dd>
<dt>
<span class="term">
<code class="literal">U+0092</code>
</span>
</dt>
<dd>
ISO-8859-1 中的右单引号 — 不会被用于 Unicode 中
</dd>
</dl>
</div>
<p><code class="literal">标准分词器</code> 和 <code class="literal">icu_分词器</code> 把这三个字符视为单词的分界线 — 一个将文本拆分为词汇单元的位置。不幸的是，一些出版社用 <code class="literal">U+201B</code> 作为名字的典型书写方式例如 <code class="literal">M‛coy</code> ，
第二个俩字符或许可以被你的文字处理软件打出来，这取决于这款软件的年纪。</p>
<p>即使在使用可以“接受”的引号标记时，一个用单引号书写的词 — <code class="literal">You’re</code> — 也和一个用撇号书写的词 — <code class="literal">You're</code> — 不一样，这意味着搜索其中的一个变体将会找不到另一个。</p>
<p>幸运的是，可以用 <code class="literal">mapping</code> 对这些混乱的字符进行分类，
该过滤器可以运行我们用另一个字符替换所有实例中的一个字符。这种情况下，我们可以简单的用 <code class="literal">U+0027</code> 替换所有的撇号变体：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">PUT /my_index
{
  "settings": {
    "analysis": {
      "char_filter": { <a id="CO137-1"></a><i class="conum" data-value="1"></i>
        "quotes": {
          "type": "mapping",
          "mappings": [ <a id="CO137-2"></a><i class="conum" data-value="2"></i>
            "\\u0091=&gt;\\u0027",
            "\\u0092=&gt;\\u0027",
            "\\u2018=&gt;\\u0027",
            "\\u2019=&gt;\\u0027",
            "\\u201B=&gt;\\u0027"
          ]
        }
      },
      "analyzer": {
        "quotes_analyzer": {
          "tokenizer":     "standard",
          "char_filter": [ "quotes" ] <a id="CO137-3"></a><i class="conum" data-value="3"></i>
        }
      }
    }
  }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO137-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>我们自定义了一个 <code class="literal">char_filter</code> （字符过滤器）叫做 <code class="literal">quotes</code> ，提供所有撇号变体到简单撇号的映射。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO137-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>为了更清晰，我们使用每个字符的 JSON Unicode 转义语句，当然我们也可以使用他们本身字符表示： <code class="literal">"‘=&gt;'"</code> 。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO137-3"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>我们用自定义的 <code class="literal">quotes</code> 字符过滤器创建一个新的分析器叫做 <code class="literal">quotes_analyzer</code> 。</p>
</td>
</tr>
</table>
</div>
<p>像以前一样，我们需要在创建了分析器后测试它：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">GET /my_index/_analyze?analyzer=quotes_analyzer
You’re my ‘favorite’ M‛Coy</pre>
</div>
<p>这个例子返回如下词汇单元，其中所有的单词中的引号标记都被替换为了撇号： <code class="literal">You're</code>, <code class="literal">my</code>, <code class="literal">favorite</code>, <code class="literal">M'Coy</code> 。</p>
<p>投入更多的努力确保你的分词器接收到高质量的输入，你的搜索结果质量也将会更好。</p>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="icu-tokenizer.html">« icu_分词器</a>
</span>
<span class="next">
<a href="token-normalization.html">归一化词元 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>